package pyrachnid.model.ground_model;

import java.util.Random;

import Event.Operation.OperationWind;

import pyrachnid.model.ObservableWithEvent;

public class Wind extends ObservableWithEvent<OperationWind> {
	private Direction _direction;
	private int _force;
	private int _nextUpdate;
	private int _oneTop;
	private Random _rd;
	
	public enum Direction
	{
		NORTH("Nord"),
		SOUTH("Sud"),
		EAST("Est"),
		WEST("Ouest"),
		NORTH_EAST("Nord-Est"),
		SOUTH_EAST("Sud-Est"),
		NORTH_WEST("Nord-Ouest"),
		SOUTH_WEST("Sud-Ouest");
		
		private final String direction;
		private Direction(String direction){
			this.direction = direction;
		}
		public String getDirection() {
			return direction;
		}
		
		@Override
		public String toString(){
			return direction;
		}
	}
	
	public Wind(Direction p_direction, int p_force) {
		if(p_force < 0)
		{
			this._force = 0;
		}
		else if(p_force > 100)
		{
			this._force = 100;
		}
		else
		{
			this._force = p_force;
		}
		this._direction = p_direction;

		// Un top toutes les secondes
		_oneTop = 250;
		_nextUpdate = _oneTop;
		
		_rd = new Random();
	}
	
	public Direction getDirection() {
		return _direction;
	}

	public int getForce() {
		return _force;
	}
	
	private void computeForce()
	{
		int windValueRand = _rd.nextInt(5);
		
		if((windValueRand == 0 && _force > 0) || (windValueRand == 1 && _force < 100))
		{
			_force += (windValueRand == 0)? -1 : 1;
			notifyObserver(this, "Value Change");
		}
	}
	
	private void computeDirection()
	{
		// 1 par minute en moyenne (600 top par minutes, 7 change de changer d'�tat)
		int windValueRand = _rd.nextInt(100);
		
		if(windValueRand < 8)
		{
			//Initialisation
			Direction newDirection;
			
			// Choose Direction
			switch(windValueRand){
			case 0:
				newDirection = Direction.NORTH;
				break;
			case 1: 
				newDirection = Direction.SOUTH;
				break;
			case 2: 
				newDirection = Direction.EAST;
				break;
			case 3: 
				newDirection = Direction.WEST;
				break;
			case 4: 
				newDirection = Direction.NORTH_EAST;
				break;
			case 5: 
				newDirection = Direction.NORTH_WEST;
				break;
			case 6: 
				newDirection = Direction.SOUTH_EAST;
				break;
			case 7: 
				newDirection = Direction.SOUTH_WEST;
				break;
			default:
				newDirection = Direction.NORTH;
				break;
			}
			
			// If new Direction, change it
			if(!newDirection.equals(_direction))
			{
				_direction = newDirection;
				notifyObserver(this, "Direction Change");
			}
		}
	}
	
	public void update(int p_time) {
		_nextUpdate -= p_time;
		
		if(_nextUpdate <= 0)
		{	
			computeForce();
			computeDirection();
			
			_nextUpdate += _oneTop;
		}
	}
}